#pragma once

#include "comm/types.h"
typedef struct list_node
{
    struct list_node* prev;
    struct list_node* next;
}list_node;


typedef struct list
{
    list_node* first;
    list_node* last;
    int count;
}list;

static inline void list_node_init(list_node* node)
{
    node->next=node->prev=(list_node*)0;
}

static inline list_node * list_node_next(list_node *node) 
{
    return node->next;
}


static inline list_node* list_first(list *list) 
{
    return list->first;
}

static inline int list_empty(list* list)
{
    if(list->count)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}


static inline int list_count(list* list)
{
    return list->count;
}


void list_init(list* list);
void list_insert_first(list* list,list_node* node);
void list_insert_last(list* list,list_node* node);

list_node* list_remove_first(list* list);
list_node* list_remove(list* list,list_node* node);

// 1.求结点在所在结构中的偏移:定义一个指向0的指针，用(struct aa *)&0->node，所得即为node字段在整个结构体的偏移
#define offset_in_parent(parent_type, node_name)    \
    ((uint32_t)&(((parent_type*)0)->node_name))

// 2.求node所在的结构体首址：node的地址 - node的偏移
// 即已知a->node的地址，求a的地址
#define offset_to_parent(node, parent_type, node_name)   \
    ((uint32_t)node - offset_in_parent(parent_type, node_name))

// 3. 进行转换: (struct aa *)addr
// list_node_parent(node_addr, struct aa, node_name)
#define list_node_parent(node, parent_type, node_name)  \
        ((parent_type *)(node ? offset_to_parent((node), parent_type, node_name) : 0))